/**
 * Created by ckto1212@gmail.com
 */
package com.welbell.android.test.camera;

import java.io.IOException;
import java.util.List;

import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.util.Log;
import android.view.SurfaceView;

/**
 * @author wangzong
 * 
 */
public class CameraVideoRecoder {

	private Camera camera;
	private Camera.Parameters cameraParameters;
	private Camera.PreviewCallback cameraPreviewCallback;

	private SurfaceView surfaceView;
	private int width = 640;
	private int height = 480;
	private int bitRate = 200000;

	private H_264CameraVideoEncoder encoder;
	private Sender sender;

	private byte[] cameraPreviewBuff;

	public CameraVideoRecoder(SurfaceView _surfaceView) {

		encoder = new H_264CameraVideoEncoder(sender, width, height, bitRate);

		this.surfaceView = _surfaceView;

		cameraPreviewCallback = new PreviewCallback() {
			@Override
			public void onPreviewFrame(byte[] data, Camera camera) {
				encoder.encodeAndSend(data);
//				log("onPreviewFrame");
				camera.addCallbackBuffer(cameraPreviewBuff);
			}
		};

		log("    ----    Init Camera    ----");

		int cameraId = -1;

		Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
		int cameraCount = Camera.getNumberOfCameras(); // get cameras number
		log("cameraCount:" + cameraCount);
		for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
			Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
			if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
				// 代表摄像头的方位，目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
				cameraId = camIdx;
			}
			log("CameraCode:" + camIdx);
		}
		if (cameraId == -1) {
			for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
				Camera.getCameraInfo(camIdx, cameraInfo); // get camerainfo
				if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
					// 代表摄像头的方位，目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
					cameraId = camIdx;
				}
			}
		}

		log("CameraId:" + cameraId);

		if (cameraId != -1) {
			try {
				camera = Camera.open(cameraId);
				log("Camera Init Success");
			} catch (Exception e) {
				log("Camera Init Failed");
				e.printStackTrace();
			}
		}

		if (camera != null) {

			camera.setPreviewCallback(cameraPreviewCallback);

			log("Init Camera Parameters");

			cameraParameters = camera.getParameters();

			List<Camera.Size> sizes = cameraParameters.getSupportedPreviewSizes();

			for (Camera.Size tempSize : sizes) {
				log("----    Supported Size:" + tempSize.width + "x" + tempSize.height);
			}

			cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); // 无闪光灯
			cameraParameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
			cameraParameters.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);

			// cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

			cameraParameters.setPreviewFormat(ImageFormat.NV21);
			cameraParameters.setPictureSize(this.width, this.height);
			cameraParameters.setPreviewSize(this.width, this.height);

			camera.setParameters(cameraParameters);

			log("Camera width:" + cameraParameters.getPictureSize().width + " height:" + cameraParameters.getPictureSize().height);

			int size = cameraParameters.getPictureSize().width * cameraParameters.getPictureSize().height;
			size = size * ImageFormat.getBitsPerPixel(cameraParameters.getPreviewFormat()) / 8;
			cameraPreviewBuff = new byte[size]; // class variable

			camera.addCallbackBuffer(cameraPreviewBuff);

			if (surfaceView != null) {
				try {
					log("Camera Set SurfaceView");
					camera.setPreviewDisplay(surfaceView.getHolder());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			log("    ----    Init Camera Success   ----");

		}

	}

	public void startCameraPreview() {
		if (camera != null) {

			log("Call StartPreview");

			camera.startPreview();

			encoder.startEncoderAndSend();
		}
	}

	public void stopCameraPreview() {
		if (camera != null) {

			log("Call StopPreview");

			camera.stopPreview();

			encoder.stopEncoderAndSend();
		}
	}

	public void release() {
		if (camera != null) {
			camera.stopPreview();
			camera.release();
		}
	}

	private void log(String _log) {
		Log.v("CameraVideoRecord", "    ----    " + _log);
	}

}
